home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-07-15 | 9.3 KB | 329 lines | [TEXT/PJMM] |
- {****************************************************}
- {}
- { CFSGameDirector.p }
- {}
- { Director methods for the game window. }
- {}
- { Copyright © 1995, Patrick Hew. All rights reserved. }
- {}
- {****************************************************}
-
-
- unit CFSGameDirector;
-
- interface
-
- uses
- TCL, FSIntf;
-
- implementation
-
- const
-
- { Dimensions. }
-
- kEdgeMargin = 8;
- kControlSpaceh = 20;
-
- kAircraftPanePosh = (kFSGameWindh - kAircraftPaneLenh) div 2;
- kAircraftPanePosv = kEdgeMargin;
-
- kDirFieldPanePosh = kFSGameWindh div 2 - kDirFieldHalfWidth;
- kDirFieldPanePosv = kAircraftPanePosv + kAircraftPaneLenv + kEdgeMargin;
-
- kAutopilotButtonLenh = 96;
- kCheckBoxLenh = 80;
- kStickPanePosh = kFSGameWindh div 2 - kStickHalfWidth;
- kAutopilotButtonPosh = kStickPanePosh - kControlSpaceh - kAutopilotButtonLenh;
- kAOACheckBoxPosh = kStickPanePosh + kStickHalfWidth * 2 + kControlSpaceh;
- kBankCheckBoxPosh = kAOACheckBoxPosh;
-
- kAutopilotButtonLenv = 36; { Measured with ClarisWorks }
- kCheckBoxesLenv = 16; { Measured with ClarisWorks }
- kControlsPosv = kDirFieldPanePosv + kDirFieldHalfHeight * 2 + kEdgeMargin;
- kAutopilotButtonPosv = kControlsPosv;
- kStickPanePosv = kControlsPosv;
- kBankCheckBoxPosv = kControlsPosv;
- kAOACheckBoxPosv = kControlsPosv + kCheckBoxesLenv + kEdgeMargin;
-
- { String constants. These, and those used in BuildWindow, should be in a }
- { resource so that the software can be localized. Of course, this is unlikely. }
- { Note that we can't have string constants produced with Concat, so we }
- { create them as variables and initialize them in IFSGameDirector. }
-
- const
- kCarriageReturn = Chr(13);
- kCommandKeySymbol = Chr(17);
-
- var
- kTakeControlStr, kReleaseControlStr, kBankStr, kAOAStr: string;
-
-
- { IFSGameDirector }
- {}
- { Post: Our game director has been initialized. }
-
- procedure CFSGameDirector.IFSGameDirector;
-
- begin { IFSGameDirector }
- IDirector(aSupervisor);
-
- itsAutopilotButton := nil;
- itsBankCheckBox := nil;
- itsAOACheckBox := nil;
- itsDirFieldPane := nil;
- itsStickPane := nil;
-
- { Start on automatic pilot. }
- isManual := FALSE;
-
- kTakeControlStr := Concat('Take', kCarriageReturn, 'Control ', kCommandKeySymbol, 'T');
- kReleaseControlStr := Concat('Release', kCarriageReturn, 'Control ', kCommandKeySymbol, 'R');
- kBankStr := Concat('Bank ', kCommandKeySymbol, 'B');
- kAOAStr := Concat('AOA ', kCommandKeySymbol, 'A');
-
- end; { IFSGameDirector }
-
-
- { Free }
- {}
- { Post: Our game director has been disposed of. }
-
- procedure CFSGameDirector.Free;
-
- begin { Free }
- { Each of the panes is in the display hierarchy, }
- { and will be disposed of in the inherited method. }
-
- itsAutopilotButton := nil;
- itsBankCheckBox := nil;
- itsAOACheckBox := nil;
- itsDirFieldPane := nil;
- itsStickPane := nil;
-
- inherited Free;
- end; { Free }
-
-
- { BuildWindow }
- {}
- { Post: The window which the game director supervises has been built. }
-
- procedure CFSGameDirector.BuildWindow;
-
- var
- theAircraftPane: CFSAircraftPane;
- theWindow: CBitmapWindow;
- theButton: CButton;
- theCheckBox: CCheckBox;
- theDirFieldPane: CFSDirFieldPane;
- thePaneBorder: CPaneBorder;
- theStickPane: CFSStickPane;
-
- begin { BuildWindow }
- { We create a window which does its drawing in an offscreen bitmap. }
- { Note that in this particular class, the window is always non-color. }
- new(theWindow);
- theWindow.IWindow(WINDGame, FALSE, gDesktop, SELF);
- itsWindow := theWindow;
-
- { The window is initially hidden, set by the resource. }
- { We don't use the decorator, because it CenterWindow puts the window at the }
- { centre of the desktop, when what we want is to centre the game and help }
- { windows on the primary screen. }
- theWindow.Move((screenBits.bounds.right - screenBits.bounds.left - kFSGameWindh - kFSHelpWindh) div 2, (screenBits.bounds.bottom - screenBits.bounds.top - kFSGameWindv) div 2 + 20);
-
- { Direction field }
-
- new(theDirFieldPane);
- theDirFieldPane.IFSDirFieldPane(itsWindow, SELF, 2 * kDirFieldHalfWidth, 2 * kDirFieldHalfHeight, kDirFieldPanePosh, kDirFieldPanePosv, sizFIXEDSTICKY, sizFIXEDSTICKY);
- itsDirFieldPane := theDirFieldPane;
-
- new(thePaneBorder);
- thePaneBorder.IPaneBorder(kBorderFrame);
- itsDirFieldPane.SetBorder(thePaneBorder);
-
- { Stability checkboxes. }
-
- new(theCheckBox);
- theCheckBox.INewCheckBox(kCheckBoxLenh, kCheckBoxesLenv, kBankCheckBoxPosh, kBankCheckBoxPosv, kBankStr, kVisible, itsWindow, SELF);
- itsBankCheckBox := theCheckBox;
- itsBankCheckBox.SetValue(BUTTON_ON); { This will update the direction field pane. }
-
- new(theCheckBox);
- theCheckBox.INewCheckBox(kCheckBoxLenh, kCheckBoxesLenv, kAOACheckBoxPosh, kAOACheckBoxPosv, kAOAStr, kVisible, itsWindow, SELF);
- itsAOACheckBox := theCheckBox;
- itsAOACheckBox.SetValue(BUTTON_ON); { This will update the direction field pane. }
-
- { Stick }
-
- new(theStickPane);
- theStickPane.IFSStickPane(itsWindow, SELF, 2 * kStickHalfWidth, 2 * kStickHalfHeight, kStickPanePosh, kStickPanePosv, sizFIXEDSTICKY, sizFIXEDSTICKY);
- itsStickPane := theStickPane;
- itsStickPane.SetWantsClicks(TRUE);
-
- new(thePaneBorder);
- thePaneBorder.IPaneBorder(kBorderFrame);
- itsStickPane.SetBorder(thePaneBorder);
-
- { Aircraft pane. }
-
- new(theAircraftPane);
- theAircraftPane.IFSAircraftPane(itsWindow, SELF, kAircraftPaneLenh, kAircraftPaneLenv, kAircraftPanePosh, kAircraftPanePosv, sizFIXEDSTICKY, sizFIXEDSTICKY);
- itsAircraftPane := theAircraftPane;
-
- new(thePaneBorder);
- thePaneBorder.IPaneBorder(kBorderFrame);
- itsAircraftPane.SetBorder(thePaneBorder);
-
- { Autopilot button. }
-
- new(theButton);
- theButton.INewButton(kAutopilotButtonLenh, kAutopilotButtonLenv, kAutopilotButtonPosh, kAutopilotButtonPosv, kTakeControlStr, kVisible, 0, itsWindow, SELF);
- theButton.SetClickCmd(cmdTakeControl);
- itsAutopilotButton := theButton;
-
- end; { BuildWindow }
-
-
- { UpdateMenus }
- {}
- { Post: The Flight menu has been configured. }
-
- procedure CFSGameDirector.UpdateMenus;
-
- begin { UpdateMenus }
- inherited UpdateMenus;
-
- if isManual then begin
- gBartender.EnableCmd(cmdReleaseControl);
- end { if }
- else begin
- gBartender.EnableCmd(cmdTakeControl);
- end; { else }
-
- end; { UpdateMenus }
-
-
- { DoCommand }
- {}
- { Post: The game director has reacted to the command with the given id. }
-
- procedure CFSGameDirector.DoCommand (theCommand: longint);
-
- var
- theMousePt: Point;
-
- begin { DoCommand }
- if theCommand = cmdTakeControl then begin
- isManual := TRUE;
-
- { Tell the stick pane to get the old mouse position }
- { ready for control measurement. }
- itsStickPane.InitOldMousePt;
-
- itsAutopilotButton.SetTitle(kReleaseControlStr);
- itsAutopilotButton.SetClickCmd(cmdReleaseControl);
- end { if }
- else if theCommand = cmdReleaseControl then begin
- isManual := FALSE;
-
- { Tell the stick pane to centre the stick. }
- itsStickPane.CentreStick;
-
- itsAutopilotButton.SetTitle(kTakeControlStr);
- itsAutopilotButton.SetClickCmd(cmdTakeControl);
- end { else if }
- else begin
- inherited DoCommand(theCommand);
- end; { else }
- end; { DoCommand }
-
-
- { DoKeyDown }
- {}
- { Post: The game director has reacted to a key down event. }
-
- procedure CFSGameDirector.DoKeyDown (theChar: char; keyCode: Byte; macEvent: EventRecord);
-
- begin { DoKeyDown }
- if (BAND(macEvent.modifiers, cmdKey) <> 0) then begin
- case theChar of
- 'a', 'A': begin
- itsAOACheckBox.SimulateClick;
- end; { 'a', 'A' }
- 'b', 'B': begin
- itsBankCheckBox.SimulateClick;
- end; { 'b', 'B' }
- 'r', 'R': begin
- if isManual then begin
- itsAutopilotButton.SimulateClick;
- end; { if }
- end; { 'r', 'R' }
- 't', 'T': begin
- if not isManual then begin
- itsAutopilotButton.SimulateClick;
- end; { if }
- end; { 't', 'T' }
- otherwise begin
- inherited DoKeyDown(theChar, keyCode, macEvent);
- end; { otherwise }
- end; { case }
- end { if }
- else begin
- inherited DoKeyDown(theChar, keyCode, macEvent)
- end; { else }
- end; { DoKeyDown }
-
-
- { ProviderChanged }
- {}
- { Post: If one of the stability check boxes has changed value, then inform the direction field. }
-
- procedure CFSGameDirector.ProviderChanged (aProvider: CCollaborator; reason: Longint; info: univ Ptr);
-
- var
- theCheckBox: CCheckBox;
-
- begin { ProviderChanged }
- if member(aProvider, CCheckbox) then begin
- theCheckBox := CCheckBox(aProvider);
- if theCheckBox = itsBankCheckBox then begin
- itsDirFieldPane.SetBankStability(theCheckBox.IsChecked);
- end { if }
- else if theCheckBox = itsAOACheckBox then begin
- itsDirFieldPane.SetAOAStability(theCheckBox.IsChecked);
- end; { else if }
- end { if }
- else begin
- inherited ProviderChanged(aProvider, reason, info);
- end; { else }
- end; { ProviderChanged }
-
-
- { Dawdle }
- {}
- { Post: The stick position has been taken, the aircrafts motion in the }
- { direction field has been updated, and used to update the aircraft. }
- { Note: Put the minimum of stuff in here, this is the main animation loop. }
-
- procedure CFSGameDirector.Dawdle (var maxSleep: longint);
-
- var
- changeBank, changeAOA: Real;
- theBank, theAOA: Real;
-
- begin { Dawdle }
- maxSleep := 0;
- if isManual then begin
- itsStickPane.GetControl(changeBank, changeAOA);
- itsDirFieldPane.UpdatePosition(changeBank, changeAOA);
- end { if }
- else begin
- itsDirFieldPane.SetCurrPosition(0, 0);
- end;
- itsDirFieldPane.GetCurrPosition(theBank, theAOA);
- itsAircraftPane.UpdateAircraft(theBank, theAOA);
- end; { Dawdle }
-
- end. { CFSGameDirector }